package de.schillermann.scriptmaster;

import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.List;
import org.bukkit.ChatColor;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.configuration.file.FileConfiguration;

/**
 * @author Mario Schillermann
 */
public class Main extends JavaPlugin {

    public FileConfiguration config; 
    
    @Override
    public void onEnable() {

        loadConfig();
        // Copy Example Files
        saveDefaultConfig(); 
        saveResource("example-script.bat", false);
        saveResource("example-script", false);
    }
    
    @Override
    public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
        
        Player player = null;

        if (!(sender instanceof Player)) {
            sender.sendMessage(ChatColor.RED + "This command can only be run by a player.");
            return true;
        }
        
        player = (Player) sender;
        
        if(!checkSizeArguments(args.length) || !checkArguments(args)) {
            player.sendMessage(getUsage());
            return true;
        }
        
        if(hasPermission(player, args)) {
            execBashScript(config.getString("script"), args, player);
        }
        
        return true;
    }
 
    private boolean hasPermission(Player player, String[] args) {

        if(player.hasPermission(
                "scriptmaster." + Arrays.toString(args)
                        .replaceAll(", ",".")
                        .replaceAll("\\[","")
                        .replaceAll("\\]",""))) {
            return true;
        }
        
        player.sendMessage(ChatColor.RED + "Sorry, you don't have enough permissions.");
        return false;
    }
    
    private boolean checkArguments(String[] arguments) {
        
        List<String> argumentList = config.getStringList("arguments");
        Integer count = 0;
        
        for (String argumentElement: argumentList) {
            
            List<String> currentArgumentList = config.getStringList(argumentElement);
            if(!currentArgumentList.contains(arguments[count])) {
                return false;
            }
                
            count++;
        }
        
        return true;
    }
    
    private boolean checkSizeArguments(Integer lengthInputArguments) {

        Integer sizeConfigArguments = config.getStringList("arguments").size();

        if(sizeConfigArguments == lengthInputArguments) {
            return true;
        }

        return false;
    }
    
    private String getUsage() {
        
        List<String> argumentList = config.getStringList("arguments");
        
        String output = "/scriptmaster ";
            
        for (String argument: argumentList) {

            List<String> currentArgumentList = config.getStringList(argument);
            output += currentArgumentList.toString()
                    .replaceAll(", ","|")
                    .replaceAll("\\[","<")
                    .replaceAll("\\]",">");
            output += " ";
        }
        
        return output;
    }
    
    public void loadConfig(){
	config = getConfig();
	config.options().copyDefaults(true);

	if(new File("plugins/ScriptMaster/config.yml").exists()){			
		System.out.println("[ScriptMaster] config.yml loaded.");	
	}else{
		saveDefaultConfig();
		System.out.println("[ScriptMaster] config.yml created and loaded.");
	}
    }

    private boolean execBashScript(String script, String[] arguments, Player player) {
        
        Process processHandler;
        String ConsoleOutput;
        String commands;
        
        commands = Arrays.toString(arguments)
            .replaceAll(",","")
            .replaceAll("\\["," ")
            .replaceAll("\\]","");

        try {
            processHandler = Runtime.getRuntime()
                    .exec(script + commands);
            
            // Console Output send to player
            BufferedReader br = new BufferedReader(
                new InputStreamReader(processHandler.getInputStream()));
            while ((ConsoleOutput = br.readLine()) != null)
            player.sendMessage(ConsoleOutput);
            
            processHandler.waitFor();
            processHandler.destroy();
            
            return true;

        } catch (Exception e) {
            return false;
        }
    }
}
